Environmental Impacts

CalCOFI was founded partly on the idea that sardine populations off the coast of California were greatly affected by environmental impacts. The region of interest, which can be seen in the following animation, is an area of great marine productivity for a variety of reasons. The California current runs south along the coast, carrying cold waters from the Arctic region down to the equator. Additionally, off shore winds drive upwelling, the process by which warm upper ocean layers are pushed towards ocean basins and cold water from the depths rises up to replace it. This water is richer in nutrients than the warmer surface waters and is a major driver of biological productivity. The following figure shows the locations of sardine larva from 1951 to 2019, as well as the amount of larva caught during the cruises.

fig = px.scatter_mapbox(larva, lat='latitude', lon='longitude', hover_name='Sardinops.sagax', zoom = 6, animation_frame='year', center = dict(lat=33, lon= -121), opacity = 1, size = 'sardine_size', color = 'Sardinops.sagax', range_color=(0, 6100))


fig.update_layout(
    mapbox_style="white-bg",
    mapbox_layers=[
        {
            "below": 'traces',
            "sourcetype": "raster",
            "sourceattribution": "United States Geological Survey",
            "source": [
                "https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}"
            ]
        }
      ])
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})


fig.show()

Sardine’s Relationship with the Ocean’s Temperature

The change in ocean temperature was originally thought to be the main factor for the decline of the pacific sardine population. Thus, we are going to explore whether the changes in our ocean’s temperature had any effect on the sardine population. First, we are going to visualize ocean temperature over the years:

fig = px.scatter_mapbox(bottle, lat='latitude', lon='longitude', hover_name = 'Avg_T_degC', color = 'Avg_T_degC', 
                        center=dict(lat=33, lon=-121), animation_frame='year', zoom=6)

fig.update_layout(
    mapbox_style="white-bg",
    mapbox_layers=[
        {
            "below": 'traces',
            "sourcetype": "raster",
            "sourceattribution": "United States Geological Survey",
            "source": [
                "https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}"
            ]
        }
      ])
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-14-8d8f220d8a59> in <module>
----> 1 bottle = pd.read_csv('/Users/user/Desktop/calcofi-book/calcofi1-book/data/sliced_bottle.csv')

~/.local/lib/python3.6/site-packages/pandas/io/parsers.py in read_csv(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, dialect, error_bad_lines, warn_bad_lines, delim_whitespace, low_memory, memory_map, float_precision)
    686     )
    687 
--> 688     return _read(filepath_or_buffer, kwds)
    689 
    690 

~/.local/lib/python3.6/site-packages/pandas/io/parsers.py in _read(filepath_or_buffer, kwds)
    452 
    453     # Create the parser.
--> 454     parser = TextFileReader(fp_or_buf, **kwds)
    455 
    456     if chunksize or iterator:

~/.local/lib/python3.6/site-packages/pandas/io/parsers.py in __init__(self, f, engine, **kwds)
    946             self.options["has_index_names"] = kwds["has_index_names"]
    947 
--> 948         self._make_engine(self.engine)
    949 
    950     def close(self):

~/.local/lib/python3.6/site-packages/pandas/io/parsers.py in _make_engine(self, engine)
   1178     def _make_engine(self, engine="c"):
   1179         if engine == "c":
-> 1180             self._engine = CParserWrapper(self.f, **self.options)
   1181         else:
   1182             if engine == "python":

~/.local/lib/python3.6/site-packages/pandas/io/parsers.py in __init__(self, src, **kwds)
   2008         kwds["usecols"] = self.usecols
   2009 
-> 2010         self._reader = parsers.TextReader(src, **kwds)
   2011         self.unnamed_cols = self._reader.unnamed_cols
   2012 

pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader.__cinit__()

pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._setup_parser_source()

FileNotFoundError: [Errno 2] No such file or directory: '/Users/user/Desktop/calcofi-book/calcofi1-book/data/sliced_bottle.csv'
fig = px.scatter_mapbox(bottle, lat='latitude', lon='longitude', hover_name = 'Avg_T_degC', color = 'Avg_T_degC', 
                        center=dict(lat=33, lon=-121), animation_frame='year', zoom=6)

fig.update_layout(
    mapbox_style="white-bg",
    mapbox_layers=[
        {
            "below": 'traces',
            "sourcetype": "raster",
            "sourceattribution": "United States Geological Survey",
            "source": [
                "https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}"
            ]
        }
      ])
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()

As expected, global temperatures have been on a rise, and this has affected ocean temperatures as well. Using this information, we are going to predict that the rise in temerature over the years would actually BENEFIT the sardine population. A study conducted by researchers from The National Marine Fisheries Service (also known as NOAA Fisheries) found that pacific sardine tend to prefer ocean temperatures at around 11C-19C. Using this information, I want to note a striking detail from our visualization which showcases that it was after the 1990s where ocean temperatures exceed 11 degrees celcius and reached the confort zone for the pacific sardine population. This is very similar to the time where the sardine population began to recover. Thus, let’s visualize to see if the sardine population was affected by temperature in any way:

bottlecast_sardine = pd.read_csv("data/bottlecast_sardine.csv")

X = bottlecast_sardine['Ocean degC'].values.reshape(-1,1)
Y = bottlecast_sardine['Sardine Larvae lbs'].values.reshape(-1,1)
linear_regressor = LinearRegression()
linear_regressor.fit(X, Y)
Y_pred = linear_regressor.predict(X)
Y = np.array(Y).reshape(-1,)
X = np.array(X).reshape(-1,)

fig = px.scatter(bottlecast_sardine, x='Ocean degC', y='Sardine Larvae lbs', trendline="ols", title = 'Ocean Temperature vs Sardine Larvae')
fig.show()
print("Pearson Correlation:", stats.pearsonr(X, Y))
Pearson Correlation: (0.2924529772129598, 0.033584728187699565)

Here we see the pearson correlation valuee of .2924 which implies a very weak correlation between ocean temperature and sardine larvae count. However, our pearson significance value of .0335 means that our results are significant, and thus, implying that there is a positive linear correlation between ocean temperature and sardine larvae. However, this model may press issue for ocean temperatures below 9 degrees celcius, as our prediction model would predict a negative amount of sardine larvae. Realistically, this cannot happen in the world, to have a negative population count. Thus, it may be beneficial to change our model to check for any expotential correlation instead of linear.

x_data = bottlecast_sardine['Ocean degC']
y_data = bottlecast_sardine['Sardine Larvae lbs']

log_x_data = np.log(x_data)
log_y_data = np.log(y_data)

curve_fit = np.polyfit(x_data, log_y_data, 1)

x_val = np.arange(8.5,12,.1)
y_val = np.exp(curve_fit[1]) * np.exp(curve_fit[0]*x_val)

fig = px.scatter(bottlecast_sardine, x='Ocean degC', y='Sardine Larvae lbs', title = 'Ocean Temperature vs Sardine Larvae')
fig.add_traces(go.Scatter(x=x_val, y=y_val, name='Regression Fit'))
fig.show()

This model may be more realistic in that it cannot produce a negative sardine larvae value. However, visually we see that our model is imperfect and has a lot of errors. While it may not be possible to accuracy predict sardine larvae amount based on ocean temperature, we can conclude that the two variables are significant enought to be related with one another in a positive correlation.

Another factor to be considered in future models is the impact of climate cycles, such as the the El Nino Souther Oscillation (ENSO) in the Pacific ocean.